package web

import (
	"context"
	"gitee.com/alex-pistachio/axel/logs"
	"github.com/cloudwego/hertz/pkg/app"
	"github.com/hertz-contrib/requestid"
	"github.com/jefferyjob/go-easy-utils/byteUtil"
	"github.com/sirupsen/logrus"
)

type IController interface {
	Prepare(c context.Context, ctx *app.RequestContext, para interface{}) error
	Execute()
	Finish()
}

type RestResponse struct {
	Code  int    `json:"code"`
	Error string `json:"error,omitempty"`
	Data  any    `json:"data,omitempty"`
}

type Controller struct {
	c          context.Context
	ctx        *app.RequestContext
	httpStatus int
	resp       RestResponse
}

func (obj *Controller) Context() context.Context {
	return obj.c
}

func (obj *Controller) RequestCtx() *app.RequestContext {
	return obj.ctx
}

func (obj *Controller) HttpStatus() int {
	return obj.httpStatus
}

func (obj *Controller) SetHttpStatus(code int) {
	obj.httpStatus = code
}

func (obj *Controller) Resp() *RestResponse {
	return &obj.resp
}

func (obj *Controller) Prepare(c context.Context, ctx *app.RequestContext, para interface{}) error {
	obj.c = c
	obj.ctx = ctx

	obj.httpStatus = 200
	obj.resp.Code = 0
	obj.resp.Error = ""
	obj.resp.Data = nil

	if err := ctx.BindAndValidate(para); err != nil {
		logs.Logger().WithFields(
			logrus.Fields{
				"req_id": requestid.Get(ctx),
				"method": byteUtil.BytesToStr(ctx.Request.Header.Method()),
				"error":  err.Error(),
			}).Error("parse request failed")

		obj.resp.Code = 400
		obj.resp.Error = "parse request params failed: " + err.Error()
		return err
	}

	return nil
}

func (obj *Controller) Execute() {

}

func (obj *Controller) Finish() {
	obj.ctx.JSON(obj.httpStatus, &obj.resp)
}
